package bean.managed;

import entity.SalesLeadEntity;
import bean.managed.util.JsfUtil;
import bean.session.RoleEntityFacade;
import bean.session.SalesLeadEntityFacade;

import entity.CustomerEntity;
import entity.RoleEntity;
import entity.SalesInquiryEntity;
import entity.SalesQuotationEntity;
import entity.SystemUserEntity;
import java.io.Serializable;
import java.util.Date;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import managedbean.AbstractBacking;
import type.CustomerType;
import util.Fixtures.Role;
import util.PasswordEncryptor;
import util.SecureRandomNumberGenerator;

@ManagedBean(name = "salesLeadEntityController")
@SessionScoped
public class SalesLeadEntityController extends AbstractBacking implements Serializable {

    private SystemUserEntity systemUser;
    private SalesLeadEntity current;
    private CustomerEntity convertSalesLead;
    private DataModel items = null;
    private DataModel searchItems = null;
    private String searchField = "firstName";
    private SalesLeadEntity salesLead;
    @EJB
    private bean.session.SalesLeadEntityFacade ejbFacade;   
    @EJB
    private RoleEntityFacade roleFacade;

    private int selectedItemIndex;
    private Date currentDate = new Date();
    private String userSearchInput;
    @ManagedProperty(value = "#{salesInquiryEntityController}")
    private SalesInquiryEntityController salesInquiryEntityController;
    private SalesInquiryEntity salesInquiry;
    private SalesQuotationEntity salesQuotation;
    @ManagedProperty(value = "#{salesQuotationEntityController}")
    private SalesQuotationEntityController salesQuotationEntityController;
    @ManagedProperty(value = "#{purchaseOrderEntityController}")
    private PurchaseOrderEntityController purchaseOrderEntityController;
    @ManagedProperty(value = "#{contactEntityController}")
    private ContactEntityController contactEntityController;

    public SalesLeadEntityController() {
    }

    public SalesLeadEntityFacade getEjbFacade() {
        return ejbFacade;
    }

    public void setEjbFacade(SalesLeadEntityFacade ejbFacade) {
        this.ejbFacade = ejbFacade;
    }

    public ContactEntityController getContactEntityController() {
        return contactEntityController;
    }

    public void setContactEntityController(ContactEntityController contactEntityController) {
        this.contactEntityController = contactEntityController;
    }

    public SalesLeadEntity getSalesLead() {
        return salesLead;
    }

    public void setSalesLead(SalesLeadEntity salesLead) {
        this.salesLead = salesLead;
    }

    public SalesQuotationEntityController getSalesQuotationEntityController() {
        return salesQuotationEntityController;
    }

    public void setSalesQuotationEntityController(SalesQuotationEntityController salesQuotationEntityController) {
        this.salesQuotationEntityController = salesQuotationEntityController;
        this.salesQuotationEntityController.setSalesLeadEntityController(this);
    }

    public SalesQuotationEntity getSalesQuotation() {
        return salesQuotation;
    }

    public void setSalesQuotation(SalesQuotationEntity salesQuotation) {
        this.salesQuotation = salesQuotation;
    }

    public SalesInquiryEntity getSalesInquiry() {
        return salesInquiry;
    }

    public void setSalesInquiry(SalesInquiryEntity salesInquiry) {
        this.salesInquiry = salesInquiry;
    }

    public CustomerEntity getConvertSalesLead() {
        if (convertSalesLead == null) {
            convertSalesLead = new CustomerEntity();
            selectedItemIndex = -1;
        }
        return convertSalesLead;
    }

    public void setConvertSalesLead(CustomerEntity convertSalesLead) {
        this.convertSalesLead = convertSalesLead;
    }

    public String getSearchField() {
        return searchField;
    }

    public void setSearchField(String searchField) {
        this.searchField = searchField;
    }

    public String getUserSearchInput() {
        return userSearchInput;
    }

    public void setUserSearchInput(String userSearchInput) {
        this.userSearchInput = userSearchInput;
    }

    public SalesLeadEntity getCurrent() {
        return current;
    }

    public void setCurrent(SalesLeadEntity current) {
        this.current = current;
    }

    public Date getCurrentDate() {
        return currentDate;
    }

    public void setCurrentDate(Date currentDate) {
        this.currentDate = currentDate;
    }

    public SalesLeadEntity getSelected() {
        if (current == null) {
            current = new SalesLeadEntity();
            selectedItemIndex = -1;
        }
        return current;
    }

    private SalesLeadEntityFacade getFacade() {
        return ejbFacade;
    }

    public String prepareSearch() {
        recreateModel();
        searchItems = getSearchItems();
        recreateModel();
        return "SearchList?faces-redirect=true";
    }

    public String prepareList() {
        recreateModel();
        return "/entities/salesLeadEntity/List?faces-redirect=true";
    }

    public String prepareView() {
        current = (SalesLeadEntity) getItems().getRowData();
        resetContactAndAddresses();
        recreateModel();
        return "View?faces-redirect=true";
    }

    public String prepareSearchView() {
        current = (SalesLeadEntity) getSearchItems().getRowData();
     
        resetContactAndAddresses();
        recreateModel();
        return "View?faces-redirect=true";
    }

     public String prepareSearchPageConvert() {
        current = (SalesLeadEntity) getSearchItems().getRowData();
       
        resetContactAndAddresses();
        return "ConvertView?faces-redirect=true";
    }
    
    public String prepareConvert() {
        current = (SalesLeadEntity) getItems().getRowData();
     
        resetContactAndAddresses();
        return "ConvertView?faces-redirect=true";
    }

    public String prepareCreate() {
        current = new SalesLeadEntity();
        selectedItemIndex = -1;
       //resetContactAndAddresses(); 
        return "/entities/salesLeadEntity/Create?faces-redirect=true";
    }
    
    public String prepareRegister() {
        current = new SalesLeadEntity();
        selectedItemIndex = -1;
        //resetContactAndAddresses();
        return "/RegisterSalesLead?faces-redirect=true";
    }
    //view from inquiry/quotation

    public String viewCreateSalesLeadFromInquiry() {
        current = salesInquiryEntityController.getViewCurrent().getSalesLead();
        //selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        resetContactAndAddresses();
        return "/entities/salesLeadEntity/View?faces-redirect=true";
    }

    public String viewSalesLeadFromInquiry() {
        current = salesInquiryEntityController.getSelected().getSalesLead();
        //selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        resetContactAndAddresses();
        return "/entities/salesLeadEntity/View?faces-redirect=true";
    }

    public String viewSalesLeadFromQuotation() {
        current = salesQuotationEntityController.getSelected().getSalesLead();
        //selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        resetContactAndAddresses();
        return "/entities/salesLeadEntity/View?faces-redirect=true";
    }

    public String viewSalesLeadFromInquiryDialog() {
        current = salesInquiry.getSalesLead();
        resetContactAndAddresses();
        return "/entities/salesLeadEntity/View?faces-redirect=true";
    }

    public String viewSalesLeadFromQuotationDialog() {
        current = salesQuotation.getSalesLead();
        resetContactAndAddresses();
        return "/entities/salesLeadEntity/View?faces-redirect=true";
    }

    public String create() {
        try {
            encryptPasswordForNew();
            createWithoutRedirect();
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesLeadEntityCreated"));
            return prepareList();
        } catch (Exception e) {
            e.printStackTrace();
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    public String createRedirectToIndex() {
        try {
            encryptPasswordForCurrent();
            createWithoutRedirect();
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesLeadEntityCreated"));
            return "/index?faces-redirect=true";
        } catch (Exception e) {
            e.printStackTrace();
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    public void createWithoutRedirect() throws Exception {
        current.getContact().setPerson(current);
        current.created(getLoginPerson());
        getFacade().create(current);
        postCreateRoleAssignment();
    }
    
    //role rights assignement
    private void postCreateRoleAssignment() {
        try {
            RoleEntity lead = roleFacade.findRole(Role.SalesLead.getName());
            current.getRoles().add(lead);
            lead.getUsers().add(current);
            roleFacade.edit(lead);
            ejbFacade.edit(current);
        } catch (Exception ex) {
            JsfUtil.addErrorMessage(ex, "Error setting createdBy and modifiedBy");
        }
    }
    
    //if created by self
    private void encryptPasswordForCurrent() {
        current.setPassword(PasswordEncryptor.encryptPassword(current.getPassword()));
    }

    //if created by sales executive
    private void encryptPasswordForNew() {
        current.setPassword(PasswordEncryptor.encryptPassword(SecureRandomNumberGenerator.nextSecureRandomNumber()));
    }


    public String prepareSearchPageEdit() {
        current = (SalesLeadEntity) getSearchItems().getRowData();
        resetContactAndAddresses();
       
        return "Edit?faces-redirect=true";
    }
    
    public String prepareEdit() {
        current = (SalesLeadEntity) getItems().getRowData();
        resetContactAndAddresses();
        
        return "Edit?faces-redirect=true";
    }
    
    private void resetContactAndAddresses(){
        contactEntityController.setupCurrent(current.getContact());
    }

    public String update() {
        try {
            current.modified(getLoginPerson());
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesLeadEntityUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            e.printStackTrace();
            return null;
        }
    }

    public String searchPageDestroy() {
        current = (SalesLeadEntity) getSearchItems().getRowData();
      
        performDestroy();
        recreateModel();
        return "List?faces-redirect=true";
    }
    
    public String destroy() {
        current = (SalesLeadEntity) getItems().getRowData();
       
        performDestroy();
        recreateModel();
        return "List?faces-redirect=true";
    }

    public String searchPageActivate() {
        current = (SalesLeadEntity) getSearchItems().getRowData();
       
        performActivate();
        recreateModel();
        return "List?faces-redirect=true";
    }
    
    public String activate() {
        current = (SalesLeadEntity) getItems().getRowData();
       
        performActivate();
        recreateModel();
        return "List?faces-redirect=true";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        update();
        return "/entities/salesLeadEntity/List?faces-redirect=true";
//        if (selectedItemIndex >= 0) {
//            return "View";
//        } else {
//            // all items were removed - go back to list
//            recreateModel();
//            return "List";
//        }
    }

    public void performDestroy() {
        try {
            current.setArchived(true);
            current.modified(getLoginPerson());
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesLeadEntityDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void performActivate() {
        try {
            current.setArchived(false);
            current.modified(getLoginPerson());
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesLeadEntityActivated"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

//    private void updateCurrentItem() {
//        int count = getFacade().count();
//        if (selectedItemIndex >= count) {
//            // selected index cannot be bigger than number of items:
//            selectedItemIndex = count - 1;
//            // go to previous page if last page disappeared:
//            if (pagination.getPageFirstItem() >= count) {
//                pagination.previousPage();
//            }
//        }
//        if (selectedItemIndex >= 0) {
//            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
//        }
//    }

    public DataModel getItems() {
        if (items == null) {
            items = getFacade().findAllSalesLead();
        }
        return items;
    }

    public DataModel getSearchItems() {
        if (searchItems == null) {
            searchItems = ejbFacade.findSalesLead(userSearchInput, searchField);
        }
        return searchItems;
    }

    public void recreateModel() {
        searchItems = null;
        items = null;
    }



    public CustomerType[] getCustomerType() {
        return CustomerType.values();
    }

    public SystemUserEntity getSystemUser() {
        return systemUser;
    }

    public void setSystemUser(SystemUserEntity systemUser) {
        this.systemUser = systemUser;
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    public SalesInquiryEntityController getSalesInquiryEntityController() {
        return salesInquiryEntityController;
    }

    public void setSalesInquiryEntityController(SalesInquiryEntityController salesInquiryEntityController) {
        this.salesInquiryEntityController = salesInquiryEntityController;
        this.salesInquiryEntityController.setSalesLeadEntityController(this);
    }

    public PurchaseOrderEntityController getPurchaseOrderEntityController() {
        return purchaseOrderEntityController;
    }

    public void setPurchaseOrderEntityController(PurchaseOrderEntityController purchaseOrderEntityController) {
        this.purchaseOrderEntityController = purchaseOrderEntityController;
        this.purchaseOrderEntityController.setSalesLeadEntityController(this);
    }

    @FacesConverter(forClass = SalesLeadEntity.class)
    public static class SalesLeadEntityControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            SalesLeadEntityController controller = (SalesLeadEntityController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "salesLeadEntityController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof SalesLeadEntity) {
                SalesLeadEntity o = (SalesLeadEntity) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + SalesLeadEntityController.class.getName());
            }
        }
    }
}
